<template>
	<div class="sc-code-editor" :style="{ height: _height }">
		<textarea ref="textarea" v-model="contentValue" />
	</div>
</template>

<script>
import { markRaw } from 'vue'
import CodeMirror from 'codemirror'
import 'codemirror/lib/codemirror.css'

// 主题
import 'codemirror/theme/idea.css'
import 'codemirror/theme/darcula.css'

// 功能插件
import 'codemirror/addon/selection/active-line'
import 'codemirror/addon/hint/show-hint'
import 'codemirror/addon/hint/sql-hint'
import 'codemirror/addon/hint/anyword-hint'
import 'codemirror/mode/sql/sql'

// 必须导入提示框样式
import 'codemirror/addon/hint/show-hint.css'

export default {
	props: {
		modelValue: String,
		mode: { type: String, default: 'javascript' },
		height: { type: [String, Number], default: 300 },
		options: { type: Object, default: () => ({}) },
		theme: { type: String, default: 'idea' },
		readOnly: Boolean,
		sqlTables: { type: Object, default: () => ({}) }
	},
	data() {
		return {
			sqlKeywords: [
				'SELECT', 'FROM', 'WHERE', 'GROUP BY', 'ORDER BY', 'HAVING',
				'INSERT INTO', 'VALUES', 'UPDATE', 'SET', 'DELETE FROM',
				'CREATE TABLE', 'ALTER TABLE', 'DROP TABLE',
				'JOIN', 'LEFT JOIN', 'RIGHT JOIN', 'INNER JOIN', 'OUTER JOIN',
				'ON', 'AS', 'DISTINCT', 'COUNT', 'SUM', 'AVG', 'MAX', 'MIN',
				'AND', 'OR', 'NOT', 'IN', 'BETWEEN', 'LIKE', 'IS NULL', 'IS NOT NULL',
				'LIMIT', 'OFFSET', 'UNION', 'UNION ALL'
			],
			contentValue: this.modelValue,
			coder: null,
			opt: {
				theme: this.theme,
				styleActiveLine: true,
				lineNumbers: true,
				lineWrapping: false,
				tabSize: 4,
				indentUnit: 4,
				indentWithTabs: true,
				mode: this.mode,
				readOnly: this.readOnly,
				hintOptions: {
					completeSingle: false,
					tables: this.sqlTables,
					customKeywords: ['CUSTOM_KEYWORD'],
					// 确保SQL提示正常工作
					disableKeywords: false
				},
				extraKeys: {
					"Ctrl-Space": "autocomplete",
					"Alt-Space": "autocomplete",
					"Space": (cm) => {
						// 仅当当前词是SQL关键字的一部分时触发
						const token = cm.getTokenAt(cm.getCursor())
						if (this.sqlKeywords.some(kw =>
							kw.toLowerCase().startsWith(token.string.toLowerCase()))) {
							CodeMirror.commands.autocomplete(cm)
						} else {
							cm.replaceSelection(" ")
						}
					}
				},
				...this.options
			}
		}
	},
	computed: {
		_height() {
			return Number(this.height) ? Number(this.height) + 'px' : this.height
		}
	},
	watch: {
		modelValue(val) {
			if (val !== this.coder?.getValue()) {
				this.contentValue = val
				this.coder?.setValue(val)
			}
		},
		sqlTables: {
			deep: true,
			handler(tables) {
				this.coder?.setOption('hintOptions', {
					...this.opt.hintOptions,
					tables
				})
			}
		},
		mode(newMode) {
			if (this.coder) {
				this.coder.setOption('mode', newMode)
				if (newMode === 'sql') {
					this.setupSQlAutocomplete()
				}
			}
		}
	},
	mounted() {
		this.init()
		if (this.mode === 'sql') {
			this.setupSQlAutocomplete()
		}
	},
	methods: {
		init() {
			this.coder = markRaw(CodeMirror.fromTextArea(this.$refs.textarea, this.opt))
			this.coder.on('change', (coder) => {
				this.contentValue = coder.getValue()
				this.$emit('update:modelValue', this.contentValue)
			})

			// 添加编辑器实例的引用，方便父组件调用
			this.$emit('editor-mounted', this.coder)
		},

		setupSQlAutocomplete() {
			CodeMirror.registerHelper('hint', 'sql', (editor, options) => {
				const cursor = editor.getCursor()
				const token = editor.getTokenAt(cursor)
				const line = editor.getLine(cursor.line)
				const textBeforeCursor = line.substring(0, cursor.ch)
				// 基础SQL关键字补全（优先）
				const baseKeywords = this.sqlKeywords
					.filter(kw => kw.toLowerCase().startsWith(token.string.toLowerCase()))
					.map(kw => kw + (kw.endsWith(' ') ? '' : ' ')) // 自动添加空格
				// 根据上下文决定提示内容
				let list = [...new Set(baseKeywords)] // 去重

				// 只有在明显需要表/列名时才添加
				if (textBeforeCursor.match(/(FROM|JOIN|INSERT INTO|UPDATE)\s+$/i)) {
					list = [...list, ...Object.keys(options.tables || {})]
				}
				else if (textBeforeCursor.match(/ON\s+.+\.$/i)) {
					const tableName = textBeforeCursor.split('.').slice(-2)[0].trim()
					list = options.tables[tableName] || []
				}
				return {
					list,
					from: CodeMirror.Pos(cursor.line, token.start),
					to: CodeMirror.Pos(cursor.line, token.end)
				}
			})
			// 自动触发配置（保持原样）
			this.coder.on('keyup', (cm, event) => {
				if (!cm.state.completionActive && /^[a-zA-Z_]$/.test(event.key)) {
					setTimeout(() => CodeMirror.commands.autocomplete(cm), 100)
				}
			})
		},

		// 方便父组件调用的方法
		refreshAutocomplete() {
			if (this.mode === 'sql') {
				this.setupSQlAutocomplete()
			}
		}
	}
}
</script>

<style scoped>
.sc-code-editor {
	font-size: 14px;
	border: 1px solid #ddd;
	line-height: 150%;
}

.sc-code-editor:deep(.CodeMirror) {
	height: 100%;
}

/* 提示框样式优化 */
.sc-code-editor:deep(.CodeMirror-hints) {
	font-family: var(--el-font-family);
	max-height: 300px;
	z-index: 9999;
	box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
	border-radius: 4px;
}

.sc-code-editor:deep(.CodeMirror-hint) {
	padding: 4px 8px;
	transition: background 0.2s;
}

.sc-code-editor:deep(.CodeMirror-hint-active) {
	background: #e0e0e0;
}
</style>
